package org.tema.web;


import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;


import org.tema.ejb.ProductBeanLocal;
import org.tema.ejb.TestSpecBeanLocal;
import org.tema.ejb.UserBeanLocal;
import org.tema.entities.Product;
import org.tema.entities.TestSpecification;
import org.tema.entities.User;

public class ManageTestSpecificationsBean {
	
	// navigation constants
	private static final String SPECS_LIST = "specsList";
	private static final String EDIT_SPEC = "editSpec";

	@EJB
	private TestSpecBeanLocal testSpecBean;
	@EJB
	private ProductBeanLocal productBean;
	@EJB
	private UserBeanLocal userBean;
	
	private String summary;
	private String description;
	private Date cDate;
	private Date mDate;
	private  TestSpecSearchTypes searchDropDown;
	private String searchWord;
	private Collection <TestSpecification> testSpecList = null;
	private int testSpecId;
	private TestSpecification singleTestSpec;
	private Product product;
	private User user;
	private HtmlDataTable dataTable;
	private HtmlInputHidden dataItemId = new HtmlInputHidden();

	public  ManageTestSpecificationsBean() {
		
	}

	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	public HtmlInputHidden getDataItemId() {
		return dataItemId;
	}

	public void setDataItemId(HtmlInputHidden dataItemId) {
		this.dataItemId = dataItemId;
	}


	public String getDescription() {
		return description;
	}


	public void setDescription(String description) {
		this.description = description;
	}
	
	///real methods besides accessors
	
	
	public TestSpecSearchTypes getSearchDropDown() {
		return searchDropDown;
	}


	public void setSearchDropDown(TestSpecSearchTypes searchDropDown) {
		this.searchDropDown = searchDropDown;
	}


	public String getSearchWord() {
		return searchWord;
	}


	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public Date getCDate() {
		return cDate;
	}

	public void setCDate(Date date) {
		date = new java.sql.Date(System.currentTimeMillis());
		cDate = date;
	}

	public Date getMDate() {
		return mDate;
	}

	public void setMDate(Date date) {
		//date = new java.sql.Date(System.currentTimeMillis());
		mDate = date;
	}

	public Collection<TestSpecification> getTestSpecList() {
		if( testSpecList == null ) {
			findAll();
		}
		return testSpecList;
	}

	public void setTestSpecList(Collection<TestSpecification> testSpecList) {
		this.testSpecList = testSpecList;
	}

	public int getTestSpecId() {
		return testSpecId;
	}

	public void setTestSpecId(int testSpecId) {
		this.testSpecId = testSpecId;
	}

	public TestSpecification getSingleTestSpec() {
		return singleTestSpec;
	}

	public void setSingleTestSpec(TestSpecification singleTestSpec) {
		this.singleTestSpec = singleTestSpec;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public void setSearchWord(String searchWord) {
		this.searchWord = searchWord;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String createTestSpec() {
		FacesContext facesContext = FacesContext.getCurrentInstance(); 
    	String creatorName = facesContext.getExternalContext().getRemoteUser();
    	User currentUser = userBean.findUserByName(creatorName);
		Date creationD  = new java.sql.Date(System.currentTimeMillis());
		Date modificationD  = new java.sql.Date(System.currentTimeMillis());
		testSpecBean.addTestSpec(getSummary(), getDescription(), creationD, modificationD, product, currentUser);
		// add status message
		Status.addInfo("Specification " + this.summary +" created. ");
		// update specs list
		findAll();
		return SPECS_LIST; 
	}
	
	public String deleteTestSpec() {
		singleTestSpec = (TestSpecification) dataTable.getRowData();
		testSpecBean.deleteTestSpec(singleTestSpec);
		// add status message
		Status.addInfo("Specification " + singleTestSpec.getSummary() + " deleted. ");
		// update specs list
		findAll();
		return SPECS_LIST;
	}
	
	public String displayTestSpec() {
		TestSpecification spec1 = (TestSpecification) dataTable.getRowData();
		this.setSingleTestSpec ( testSpecBean.findTestSpecById(spec1.getId()) );
		return EDIT_SPEC;
	}
	
	
	public String editTestSpec() {
		FacesContext facesContext = FacesContext.getCurrentInstance(); 
    	String modifierName = facesContext.getExternalContext().getRemoteUser();
    	User currentUser = userBean.findUserByName(modifierName);
    	singleTestSpec.setModifier(currentUser);
		Date date = new Date (System.currentTimeMillis());
		singleTestSpec.setModificationDate(date);
		testSpecBean.updateTestSpec(getSingleTestSpec(), currentUser);
		// add status message
		Status.addInfo("Specification " + singleTestSpec.getSummary() +" modified. ");
		// update specs list
		findAll();
		return SPECS_LIST;
	}
	
	
	public String  selectSearch(){
		String result;
		switch (this.getSearchDropDown()) {
        case ID:  result = findById( this.getSearchWord()); break;
        case SUMMARY:  result = findBySummary(this.getSearchWord()); break;
        case PRODUCTID:  result = findByProductId(this.getSearchWord()); break;
        case PRODUCTNAME:  result = findByProductName(this.getSearchWord()); break;
        case CREATIOND:  result = findByCreationD(this.getSearchWord()); break;
        case MODIFICATIOND:  result = findByModificationD(this.getSearchWord()); break;
        case CREATOR:  result = findByCreatorName(this.getSearchWord()); break;
        case MODIFIER:  result = findByModifierName(this.getSearchWord()); break;
        case ALLTESTSPECS: result = findAll();
        default: result = findAll();
		}
		return result;
	}
	
	////
	public String  findAll(){
		//String result;
		setTestSpecList( ( Collection <TestSpecification> ) testSpecBean.findAllTestSpecs());
		if ( ! getTestSpecList().isEmpty() ){
			return SPECS_LIST;
		}
		else {
			return SPECS_LIST;
		}
	}
	
	public String  findById(String searchWord){
		setTestSpecId( Integer.parseInt(searchWord));
		try {
			setSingleTestSpec( testSpecBean.findTestSpecById(getTestSpecId()));
			this.setTestSpecList(Arrays.asList(singleTestSpec));
	/*		return SPECS_LIST;
		} catch (NoResultException e) {
			return SPECS_LIST;
		}
		catch(IllegalArgumentException il){
			return SPECS_LIST;
		}
		*/
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	}
	
	
	
	@SuppressWarnings("unchecked")
	public String findBySummary( String searchWord){
			try {
				setTestSpecList( ( Collection <TestSpecification> ) testSpecBean.findTestSpecsBySummary(searchWord));
				if (  getTestSpecList().isEmpty() ){
					Status.addInfo("No specs available with name: " + searchWord );
				}
				
			}
			catch(IllegalArgumentException il){
				Status.addError(il.getCause().getMessage());
			}
			catch(EJBException e){
				Status.addError(e.getCause().getMessage());
			}
			return SPECS_LIST;
	}

	
	@SuppressWarnings("unchecked")
	public String findByProductId(String searchWord ){
		try{
			int id =  Integer.parseInt(searchWord);
			Product p = productBean.findProductById( id );
			this.setTestSpecList( (Collection <TestSpecification>) p.getTestSpecificationSet() );
			if ( getTestSpecList().isEmpty() ){
				Status.addInfo("No specs available with name: " + id );
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	}
	
	
	public String findByProductName(String SearchWord ){
		try{
			this.setTestSpecList( (Collection <TestSpecification>) productBean.findProductByName(searchWord).getTestSpecificationSet() );
			if (  getTestSpecList().isEmpty() ){
				Status.addInfo("No specs available with name: " + SearchWord );
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	}
	
	//convert string to date for the creation and modification dates
	public Date convertString (String strDate){
		Date date = null;
		try{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:MM");
			date = new Date( sdf.parse(strDate).getTime() );
		}catch(ParseException pe){
			pe.getMessage();
			pe.printStackTrace();
		}
		return date;
	}
	
	
	public String findByCreationD(String cDate){
		try{
			this.setTestSpecList( (Collection <TestSpecification>) testSpecBean.findTestSpecByCDate( convertString(cDate) )   );
			if( this.getTestSpecList().isEmpty() ){
				Status.addInfo("No specs available with creation date: " + cDate );	
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	}
	
	public String findByModificationD(String cDate){
		try{
			this.setTestSpecList( (Collection <TestSpecification>) testSpecBean.findTestSpecByMDate( convertString(cDate) )   );
			if( this.getTestSpecList().isEmpty() ){
				Status.addInfo("No specs available with modification date: " + cDate );	
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	}
	
	public String findByCreatorName(String cName){
		try{
			this.setTestSpecList( (Collection <TestSpecification>) testSpecBean.findTestSpecByCreatorName(cName)  );
			if( this.getTestSpecList().isEmpty() ){
				Status.addInfo("No specs available with creator: " + cName );	
			}
		}
		catch(EJBException e){
			Status.addError(e.getCause().getMessage());
		}
		return SPECS_LIST;
	
	}
	
	public String findByModifierName(String mName){
		try{
			this.setTestSpecList( (Collection <TestSpecification>) testSpecBean.findTestSpecByModifierName(mName)  );
		}
		catch( EJBException e){
			Status.addInfo("No specs available with modifier: " + mName );
		}
		
		return SPECS_LIST;
	}
	
    public Collection<SelectItem> getItems() {
    	TestSpecSearchTypes[] values = TestSpecSearchTypes.values();
        Collection<SelectItem> list = new ArrayList<SelectItem>(values.length);
        for (TestSpecSearchTypes value : values) { 
        	list.add(new SelectItem(value, value.getLabel()));            
        } 
        return list;
    }
    
    //create selectItems from the product names
    public Collection<SelectItem> getProductList(){
    	Collection<Product> products = productBean.findAllProducts();
    	Collection <SelectItem> productList = new ArrayList<SelectItem>( products.size() );  	
    	for( Product prod : products ){
    		productList.add( new SelectItem( prod, prod.getName() ) );
    	}
    	return productList;
    }
    
    public Converter getProductConverter() {
    	return new ProductConverter(productBean);
    }

}
